#include "LibGL/GxGLCamera.h"
#include "math.h"
#include "gl/gl.h"
#include "gl/glu.h"

namespace GxRendering
{
	Camera::Camera()
	{
		Reset();
		CanFly = true;
	}

	void Camera::GetInverseRotationMatrix(float mat[9])
	{
		vec3 left = VectorCross(dir, up);
		Normalize(left,left);
		mat[0] = left.x; mat[1] = up.x; mat[2] = -dir.x;
		mat[3] = left.y; mat[4] = up.y; mat[5] = -dir.y;
		mat[6] = left.z; mat[7] = up.z; mat[8] = -dir.z;
	}

	void Camera::Reset()
	{
		alpha = (float)PI;
		beta = 0.0f;
		pos = vec3(0.0f,0.0f,0.0f);
		up = vec3(0.0f,1.0f,0.0f);
		dir = vec3(0.0f,0.0f,-1.0f);
	}

	void Camera::GoForward(float u)
	{
		vec3 vp;
		if (CanFly) 
		{
			pos += dir*u;
		}
		else
		{
			vp.x = sin(alpha);
			vp.z = cos(alpha);
			pos += vp*u;
		}
	}

	void Camera::MoveLeft(float u)
	{
		vec3 l, vp;
		vp.x = sin(alpha);
		vp.z = cos(alpha);
		l.x=vp.z;	l.y=0;	l.z=-vp.x;
		pos += l*u;
	}

	void Camera::TurnLeft(float u)
	{
		alpha += u;
	}

	void Camera::TurnUp(float u)
	{
		beta += u;
		if (beta > (float)PI/2)
			beta=(float)PI/2;
		if (beta < (float)-PI/2)
			beta=-(float)PI/2;
	}

	void Camera::Transform()
	{
		dir = vec3((float)sin(alpha)*cos(beta),
				   (float)sin(beta),
				   (float)cos(alpha)*cos(beta));
		up = vec3((float)sin(alpha)*cos(PI/2+beta),
				  (float)sin(PI/2+beta),
				  (float)cos(alpha)*(float)cos(PI/2+beta));
		gluLookAt(pos.x,pos.y,pos.z,
				  pos.x+dir.x,pos.y+dir.y,pos.z+dir.z,
				  up.x,up.y,up.z);
	}
}